<!DOCTYPE html>
<html>
<head>
    <title>Simple Pendulum Diagram</title>
</head>
<body>
<canvas id="canvas" width="600" height="550"></canvas>
<script>
    const canvas = document.getElementById('canvas');
    const ctx = canvas.getContext('2d');

    // --- Style and parameters ---
    ctx.strokeStyle = 'black';
    ctx.fillStyle = 'black';
    ctx.font = '18px sans-serif';

    // --- Main geometry parameters ---
    const pivotX = 300;
    const pivotY = 70;
    const L_px = 300;
    const bobR = 18;
    const angle = 23 * Math.PI / 180; // Max swing angle in radians

    // --- Calculated coordinates ---
    const eqX = pivotX;
    const eqY = pivotY + L_px;
    const rightX = pivotX + L_px * Math.sin(angle);
    const rightY = pivotY + L_px * Math.cos(angle);
    const leftX = pivotX - L_px * Math.sin(angle);
    const leftY = rightY;

    // --- Helper function for drawing arrowheads ---
    // Draws a V-shaped arrowhead at (x, y) pointing in the direction of 'angle'.
    function drawArrowHead(ctx, x, y, angle, size = 10) {
        ctx.save();
        ctx.translate(x, y);
        ctx.rotate(angle);
        ctx.beginPath();
        ctx.moveTo(0, 0);
        ctx.lineTo(-size, -size / 2.5);
        ctx.moveTo(0, 0);
        ctx.lineTo(-size, size / 2.5);
        ctx.stroke();
        ctx.restore();
    }

    // --- 1. Draw Support ---
    ctx.lineWidth = 1.5;
    ctx.beginPath();
    ctx.moveTo(pivotX - 120, pivotY);
    ctx.lineTo(pivotX + 120, pivotY);
    ctx.stroke();
    // Hatching lines for the fixed surface
    ctx.save();
    ctx.lineWidth = 1;
    for (let i = -115; i < 120; i += 10) {
        ctx.beginPath();
        ctx.moveTo(pivotX + i, pivotY);
        ctx.lineTo(pivotX + i - 10, pivotY - 15);
        ctx.stroke();
    }
    ctx.restore();

    // --- 2. Draw Dashed Guide Lines ---
    ctx.save();
    ctx.lineWidth = 1;
    ctx.setLineDash([5, 5]);
    // Top horizontal line
    ctx.beginPath();
    ctx.moveTo(50, pivotY);
    ctx.lineTo(550, pivotY);
    ctx.stroke();
    // Bottom horizontal line (at equilibrium level)
    ctx.beginPath();
    ctx.moveTo(50, eqY);
    ctx.lineTo(550, eqY);
    ctx.stroke();
    ctx.restore();

    // --- 3. Draw Pendulum Positions ---
    ctx.lineWidth = 2;

    // Dashed lines for equilibrium and left positions
    ctx.save();
    ctx.setLineDash([5, 5]);
    // Equilibrium position
    ctx.beginPath();
    ctx.moveTo(pivotX, pivotY);
    ctx.lineTo(eqX, eqY);
    ctx.stroke();
    ctx.beginPath();
    ctx.arc(eqX, eqY, bobR, 0, 2 * Math.PI);
    ctx.stroke();
    // Left extreme position
    ctx.beginPath();
    ctx.moveTo(pivotX, pivotY);
    ctx.lineTo(leftX, leftY);
    ctx.stroke();
    ctx.beginPath();
    ctx.arc(leftX, leftY, bobR, 0, 2 * Math.PI);
    ctx.stroke();
    ctx.restore();

    // Solid line for the right extreme position
    ctx.beginPath();
    ctx.moveTo(pivotX, pivotY);
    ctx.lineTo(rightX, rightY);
    ctx.stroke();
    ctx.beginPath();
    ctx.arc(rightX, rightY, bobR, 0, 2 * Math.PI);
    ctx.stroke();

    // --- 4. Draw Labels and Annotations ---
    ctx.lineWidth = 1;
    ctx.textAlign = 'left';
    ctx.textBaseline = 'middle';

    // Label: "string"
    ctx.fillText('string', 450, 190);
    ctx.beginPath();
    ctx.moveTo(445, 190);
    ctx.lineTo(rightX - 25, rightY - 100);
    ctx.stroke();

    // Label: "bob"
    ctx.fillText('bob', 470, 385);
    ctx.beginPath();
    ctx.moveTo(465, 385);
    ctx.lineTo(rightX + bobR, rightY);
    ctx.stroke();

    // Label: "equilibrium position"
    ctx.textAlign = 'right';
    ctx.fillText('equilibrium', 200, 350);
    ctx.fillText('position', 200, 370);
    ctx.beginPath();
    ctx.moveTo(205, 360);
    ctx.lineTo(eqX - bobR - 2, eqY);
    ctx.stroke();

    // Dimension line for length "L"
    const L_line_x = 70;
    ctx.beginPath();
    ctx.moveTo(L_line_x, pivotY);
    ctx.lineTo(L_line_x, eqY);
    ctx.stroke();
    drawArrowHead(ctx, L_line_x, pivotY, -Math.PI / 2); // Arrow pointing up
    drawArrowHead(ctx, L_line_x, eqY, Math.PI / 2);   // Arrow pointing down
    ctx.textAlign = 'center';
    ctx.fillText('L', L_line_x, (pivotY + eqY) / 2);

    // Displacement arrow for "x"
    ctx.beginPath();
    ctx.moveTo(eqX, eqY);
    ctx.lineTo(rightX, eqY);
    ctx.stroke();
    drawArrowHead(ctx, rightX, eqY, 0); // Arrow pointing right
    ctx.textAlign = 'center';
    ctx.textBaseline = 'bottom';
    ctx.fillText('x', rightX - bobR, eqY - 8);

    // --- 5. Draw Oscillation Arrow ---
    const osc_arc_center_x = eqX;
    const osc_arc_y_base = eqY + 45;
    const osc_arc_radius = (rightX - eqX) * 0.95;
    const osc_arc_center_y = osc_arc_y_base + osc_arc_radius;
    const angle_range = 0.3;
    const start_angle = Math.PI + angle_range; // right side of arc
    const end_angle = 2 * Math.PI - angle_range; // left side of arc

    ctx.beginPath();
    ctx.arc(osc_arc_center_x, osc_arc_center_y, osc_arc_radius, start_angle, end_angle);
    ctx.stroke();

    // Arrowheads for the oscillation arc
    const startX_arc = osc_arc_center_x + osc_arc_radius * Math.cos(start_angle);
    const startY_arc = osc_arc_center_y + osc_arc_radius * Math.sin(start_angle);
    drawArrowHead(ctx, startX_arc, startY_arc, start_angle + Math.PI / 2, 12); // Points right

    const endX_arc = osc_arc_center_x + osc_arc_radius * Math.cos(end_angle);
    const endY_arc = osc_arc_center_y + osc_arc_radius * Math.sin(end_angle);
    drawArrowHead(ctx, endX_arc, endY_arc, end_angle - Math.PI / 2, 12); // Points left

    ctx.textAlign = 'center';
    ctx.textBaseline = 'middle';
    ctx.fillText('oscillations', osc_arc_center_x, osc_arc_y_base + 10);

    // --- 6. Draw Figure Caption ---
    ctx.fillText('Fig. 4.1 (not to scale)', 300, 530);

</script>
</body>
</html>